home *** CD-ROM | disk | FTP | other *** search
/ The World's Largest Collection of Windows Software / The World's Largest Collection of Windows Software - Disc 2.iso / textproc / _j1 / tex2rtf / src / htmlutil.cc < prev    next >
C/C++ Source or Header  |  1993-10-26  |  23KB  |  969 lines

  1. /*
  2.  * htmlutil.cc
  3.  *
  4.  * Utility functions for helping convert Latex files
  5.  * into HTML files.
  6.  * files.
  7.  *
  8.  * Julian Smart September 1993
  9.  *
  10.  */
  11.  
  12. #include <wx.h>
  13. #include "tex2any.h"
  14. #include "tex2rtf.h"
  15.  
  16. char *ChaptersName = NULL;
  17. char *SectionsName = NULL;
  18. char *SubsectionsName = NULL;
  19. char *SubsubsectionsName = NULL;
  20.  
  21. static TexChunk *descriptionItemArg = NULL;
  22. static TexChunk *helpRefFilename = NULL;
  23. static TexChunk *helpRefText = NULL;
  24. static int indentLevel = 0;
  25. extern FILE *Contents;
  26. FILE *Titlepage = NULL;
  27. int fileId = 0;
  28.  
  29. // Are we in verbatim mode? If so, format differently.
  30. static Bool inVerbatim = FALSE;
  31.  
  32. // This is defined in the Tex2Any library.
  33. extern char *BigBuffer;
  34.  
  35. class HyperReference: public wxObject
  36. {
  37.  public:
  38.   char *refName;
  39.   char *refFile;
  40.   HyperReference(char *name, char *file)
  41.   {
  42.     if (name) refName = copystring(name);
  43.     if (file) refFile = copystring(file);
  44.   }
  45.  
  46. };
  47.  
  48. /*
  49.  * Close former filedescriptor and reopen using another filename.
  50.  *
  51.  */
  52.  
  53. void ReopenFile(FILE **fd, char **fileName)
  54. {
  55.   if (*fd)
  56.   {
  57.     fclose(*fd);
  58.   }
  59.   fileId ++;
  60.   char buf[200];
  61.   sprintf(buf, "%s%d.html", FileRoot, fileId);
  62.   if (*fileName) delete[] *fileName;
  63.   *fileName = copystring(FileNameFromPath(buf));
  64.   *fd = fopen(buf, "w");
  65. }
  66.  
  67. /*
  68.  * Given a TexChunk with a string value, scans through the string
  69.  * converting Latex-isms into HTML-isms, such as 2 newlines -> <P>.
  70.  *
  71.  */
  72.  
  73. void ProcessText2HTML(TexChunk *chunk)
  74. {
  75.   Bool changed = FALSE;
  76.   int ptr = 0;
  77.   int i = 0;
  78.   char ch = 1;
  79.   int len = strlen(chunk->value);
  80.   while (ch != 0)
  81.   {
  82.     ch = chunk->value[i];
  83.  
  84.     // 2 newlines means \par
  85.     if (!inVerbatim && chunk->value[i] == 10 && ((len > i+1 && chunk->value[i+1] == 10) ||
  86.                         ((len > i+1 && chunk->value[i+1] == 13) &&
  87.                         (len > i+2 && chunk->value[i+2] == 10))))
  88.     {
  89.       BigBuffer[ptr] = 0; strcat(BigBuffer, "<P>\n\n"); ptr += 5;
  90.       i += 2;
  91.       changed = TRUE;
  92.     }
  93.     else if (!inVerbatim && ch == '`' && (len >= i+1 && chunk->value[i+1] == '`'))
  94.     {
  95.       BigBuffer[ptr] = '"'; ptr ++;
  96.       i += 2;
  97.       changed = TRUE;
  98.     }
  99.     else if (!inVerbatim && ch == '`') // Change ` to '
  100.     {
  101.       BigBuffer[ptr] = 39; ptr ++;
  102.       i += 1;
  103.       changed = TRUE;
  104.     }
  105.     else
  106.     {
  107.       BigBuffer[ptr] = ch;
  108.       i ++;
  109.       ptr ++;
  110.     }
  111.   }
  112.   BigBuffer[ptr] = 0;
  113.  
  114.   if (changed)
  115.   {
  116.     delete chunk->value;
  117.     chunk->value = copystring(BigBuffer);
  118.   }
  119. }
  120.  
  121. /*
  122.  * Scan through all chunks starting from the given one,
  123.  * calling ProcessText2HTML to convert Latex-isms to RTF-isms.
  124.  * This should be called after Tex2Any has parsed the file,
  125.  * and before TraverseDocument is called.
  126.  *
  127.  */
  128.  
  129. void Text2HTML(TexChunk *chunk)
  130. {
  131.   switch (chunk->type)
  132.   {
  133.     case CHUNK_TYPE_MACRO:
  134.     {
  135.       TexMacroDef *def = NULL;
  136.       wxNode *node = MacroDefs.Find(chunk->name);
  137.  
  138.       if (node)
  139.       {
  140.         def = (TexMacroDef *)node->Data();
  141.         if (def->ignore)
  142.           return;
  143.       }
  144.  
  145.       if (def && strcmp(def->name, "verbatim") == 0)
  146.         inVerbatim = TRUE;
  147.  
  148.       node = chunk->children.First();
  149.       while (node)
  150.       {
  151.         TexChunk *child_chunk = (TexChunk *)node->Data();
  152.         Text2HTML(child_chunk);
  153.         node = node->Next();
  154.       }
  155.  
  156.       if (def && strcmp(def->name, "verbatim") == 0)
  157.         inVerbatim = FALSE;
  158.  
  159.       break;
  160.     }
  161.     case CHUNK_TYPE_ARG:
  162.     {
  163.       wxNode *node = chunk->children.First();
  164.       while (node)
  165.       {
  166.         TexChunk *child_chunk = (TexChunk *)node->Data();
  167.         Text2HTML(child_chunk);
  168.         node = node->Next();
  169.       }
  170.  
  171.       break;
  172.     }
  173.     case CHUNK_TYPE_STRING:
  174.     {
  175.       if (chunk->value)
  176.         ProcessText2HTML(chunk);
  177.       break;
  178.     }
  179.   }
  180. }
  181.  
  182. // Called on start/end of macro examination
  183. void HTMLOnMacro(char *name, int no_args, Bool start)
  184. {
  185.   if (strcmp(name, "chapter") == 0 || strcmp(name, "chapter*") == 0 || strcmp(name, "myheading") == 0)
  186.   {
  187.     if (start)
  188.     {
  189.       if (CurrentLabel)
  190.       {
  191.         delete[] CurrentLabel;
  192.         CurrentLabel = NULL;
  193.       }
  194.       ReopenFile(&Chapters, &ChaptersName);
  195.  
  196.       SetCurrentOutput(NULL);
  197.       startedSections = TRUE;
  198.     }
  199.     else
  200.     {
  201.       char *topicName = FindTopicName(GetNextChunk());
  202.       AddTexRef(topicName, ChaptersName, "chapter");
  203.  
  204.       SetCurrentOutput(Chapters);
  205.       TexOutput("<title>");
  206.       TraverseChildrenFromChunk(currentSection);
  207.       TexOutput("</title>\n");
  208.  
  209.       SetCurrentOutputs(Contents, Chapters);
  210.       fprintf(Contents, "\n<LI><A HREF=\"%s#%s\">\n", ChaptersName, topicName);
  211.  
  212.       fprintf(Chapters, "<A NAME=\"%s\">\n<H2>", topicName);
  213.       TraverseChildrenFromChunk(currentSection);
  214.       fprintf(Contents, "\n</A>\n");
  215.       fprintf(Chapters, "</H2>\n</A>\n");
  216.  
  217.       SetCurrentOutput(Chapters);
  218.     }
  219.   }
  220.   else if (strcmp(name, "section") == 0 || strcmp(name, "section*") == 0 ||
  221.            strcmp(name, "gloss") == 0 || strcmp(name, "problem") == 0)
  222.   {
  223.     if (start)
  224.     {
  225.       if (CurrentLabel)
  226.       {
  227.         delete[] CurrentLabel;
  228.         CurrentLabel = NULL;
  229.       }
  230.       ReopenFile(&Sections, &SectionsName);
  231.       SetCurrentOutput(NULL);
  232.       startedSections = TRUE;
  233.     }
  234.     else
  235.     {
  236.       char *topicName = FindTopicName(GetNextChunk());
  237.       AddTexRef(topicName, SectionsName, "section");
  238.  
  239.       SetCurrentOutput(Sections);
  240.       TexOutput("<title>");
  241.       TraverseChildrenFromChunk(currentSection);
  242.       TexOutput("</title>\n");
  243.  
  244.       FILE *jumpFrom = ((DocumentStyle == LATEX_ARTICLE) ? Contents : Chapters);
  245.  
  246.       SetCurrentOutputs(jumpFrom, Sections);
  247.       if (DocumentStyle == LATEX_ARTICLE)
  248.         fprintf(jumpFrom, "\n<LI><A HREF=\"%s#%s\">\n", SectionsName, topicName);
  249.       else
  250.         fprintf(jumpFrom, "\n<A HREF=\"%s#%s\">\n<B>", SectionsName, topicName);
  251.  
  252.       fprintf(Sections, "<A NAME=\"%s\">\n<H2>", topicName);
  253.       TraverseChildrenFromChunk(currentSection);
  254.  
  255.       if (DocumentStyle == LATEX_ARTICLE)
  256.         fprintf(jumpFrom, "\n</A>\n");
  257.       else
  258.         fprintf(jumpFrom, "</B>\n</A><P>\n");
  259.       fprintf(Sections, "</H2>\n</A>\n");
  260.  
  261.       SetCurrentOutput(Sections);
  262.     }
  263.   }
  264.   else if (strcmp(name, "references") == 0)
  265.   {
  266.     char *jumpToName;
  267.     FILE *jumpTo;
  268.     if (DocumentStyle == LATEX_ARTICLE)
  269.     {
  270.       jumpToName = SectionsName;
  271.       jumpTo = Sections;
  272.     }
  273.     else
  274.     {
  275.       jumpToName = ChaptersName;
  276.       jumpTo = Chapters;
  277.     }
  278.     if (start)
  279.     {
  280.       if (CurrentLabel)
  281.       {
  282.         delete[] CurrentLabel;
  283.         CurrentLabel = NULL;
  284.       }
  285.       ReopenFile(&jumpTo, &jumpToName);
  286.  
  287.       startedSections = TRUE;
  288.  
  289.       SetCurrentOutput(jumpTo);
  290.       TexOutput("<title>References</title>\n");
  291.  
  292.       char *topicName = "references";
  293.       SetCurrentOutputs(Contents, jumpTo);
  294.       fprintf(Contents, "\n<LI><A HREF=\"%s#%s\">\n", jumpToName, topicName);
  295.  
  296.       fprintf(jumpTo, "<A NAME=\"%s\">\n<H2>", topicName);
  297.       TexOutput("References");
  298.       fprintf(Contents, "\n</A>\n");
  299.       fprintf(jumpTo, "</H2>\n</A>\n");
  300.  
  301.       SetCurrentOutput(jumpTo);
  302.       TexOutput("<DL>\n");
  303.     }
  304.   }
  305.   else if (strcmp(name, "subsection") == 0 || strcmp(name, "subsection*") == 0 ||
  306.            strcmp(name, "membersection") == 0 || strcmp(name, "functionsection") == 0)
  307.   {
  308.     if (start)
  309.     {
  310.       if (CurrentLabel)
  311.       {
  312.         delete[] CurrentLabel;
  313.         CurrentLabel = NULL;
  314.       }
  315.       ReopenFile(&Subsections, &SubsectionsName);
  316.  
  317.       SetCurrentOutput(NULL);
  318.       startedSections = TRUE;
  319.     }
  320.     else
  321.     {
  322.       char *topicName = FindTopicName(GetNextChunk());
  323.       AddTexRef(topicName, SubsectionsName, "subsection");
  324.  
  325.       SetCurrentOutput(Subsections);
  326.       TexOutput("<title>");
  327.       TraverseChildrenFromChunk(currentSection);
  328.       TexOutput("</title>\n");
  329.  
  330.       SetCurrentOutputs(Sections, Subsections);
  331.       fprintf(Sections, "\n<A HREF=\"%s#%s\">\n<B>", SubsectionsName, topicName);
  332.       fprintf(Subsections, "<A NAME=\"%s\">\n<H2>", topicName);
  333.       TraverseChildrenFromChunk(currentSection);
  334.       fprintf(Sections, "</B>\n</A><P>\n");
  335.       fprintf(Subsections, "</H2>\n</A>\n");
  336.  
  337.       SetCurrentOutput(Subsections);
  338.     }
  339.   }
  340.   else if (strcmp(name, "subsubsection") == 0)
  341.   {
  342.     if (start)
  343.     {
  344.       if (CurrentLabel)
  345.       {
  346.         delete[] CurrentLabel;
  347.         CurrentLabel = NULL;
  348.       }
  349.       ReopenFile(&Subsubsections, &SubsubsectionsName);
  350.       SetCurrentOutput(NULL);
  351.       startedSections = TRUE;
  352.     }
  353.     else
  354.     {
  355.       char *topicName = FindTopicName(GetNextChunk());
  356.       AddTexRef(topicName, SubsubsectionsName, "subsubsection");
  357.  
  358.       SetCurrentOutput(Subsubsections);
  359.       TexOutput("<title>");
  360.       TraverseChildrenFromChunk(currentSection);
  361.       TexOutput("</title>\n");
  362.  
  363.       SetCurrentOutputs(Subsections, Subsubsections);
  364.       fprintf(Subsections, "\n<A HREF=\"%s#%s\">\n<B>", SubsubsectionsName, topicName);
  365.       fprintf(Subsubsections, "<A NAME=\"%s\">\n<H3>", topicName);
  366.       TraverseChildrenFromChunk(currentSection);
  367.       fprintf(Subsections, "</B>\n</A><P>\n");
  368.       fprintf(Subsubsections, "</H3>\n</A>\n");
  369.  
  370.       SetCurrentOutput(Subsubsections);
  371.     }
  372.   }
  373.   else if ((strcmp(name, "func") == 0) || (strcmp(name, "pfunc") == 0))
  374.   {
  375.     SetCurrentOutput(Subsections);
  376.     if (start)
  377.     {
  378.     }
  379.     else
  380.     {
  381.     }
  382.   }
  383.   else if (strcmp(name, "clipsfunc") == 0)
  384.   {
  385.     SetCurrentOutput(Subsections);
  386.     if (start)
  387.     {
  388.     }
  389.     else
  390.     {
  391.     }
  392.   }
  393.   else if (strcmp(name, "member") == 0)
  394.   {
  395.     SetCurrentOutput(Subsections);
  396.     if (start)
  397.     {
  398.     }
  399.     else
  400.     {
  401.     }
  402.   }
  403.   else if ((strcmp(name, "void") == 0) && start)
  404.     TexOutput("<B>void</B>");
  405.   else if ((strcmp(name, "hardy") == 0) && start)
  406.     TexOutput("HARDY");
  407.   else if ((strcmp(name, "wxclips") == 0) && start)
  408.     TexOutput("wxCLIPS");
  409.   else if ((strcmp(name, "&") == 0) && start)
  410.     TexOutput("&");
  411.   else if ((strcmp(name, "\\") == 0) && start)
  412.     TexOutput("\n");
  413.   else if ((strcmp(name, "rtfsp") == 0) && start) // Explicit space, RTF only
  414.     {}
  415.   else if ((strcmp(name, "itemize") == 0) ||
  416.            (strcmp(name, "enumerate") == 0) ||
  417.            (strcmp(name, "description") == 0))
  418.   {
  419.     if (start)
  420.     {
  421.       indentLevel ++;
  422.  
  423.       int listType;
  424.       if (strcmp(name, "enumerate") == 0)
  425.         listType = LATEX_ENUMERATE;
  426.       else if (strcmp(name, "itemize") == 0)
  427.         listType = LATEX_ITEMIZE;
  428.       else
  429.         listType = LATEX_DESCRIPTION;
  430.  
  431.       itemizeStack.Insert(new ItemizeStruc(listType));
  432.       switch (listType)
  433.       {
  434.         case LATEX_ITEMIZE:
  435.           TexOutput("<UL>\n");
  436.           break;
  437.         case LATEX_ENUMERATE:
  438.           TexOutput("<OL>\n");
  439.           break;
  440.         case LATEX_DESCRIPTION:
  441.           TexOutput("<DL>\n");
  442.           break;
  443.       }
  444.     }
  445.     else
  446.     {
  447.       indentLevel --;
  448.       if (itemizeStack.First())
  449.       {
  450.         ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
  451.         switch (struc->listType)
  452.         {
  453.           case LATEX_ITEMIZE:
  454.             TexOutput("</UL>\n");
  455.             break;
  456.           case LATEX_ENUMERATE:
  457.             TexOutput("</OL>\n");
  458.             break;
  459.           case LATEX_DESCRIPTION:
  460.             TexOutput("</DL>\n");
  461.             break;
  462.         }
  463.  
  464.         delete struc;
  465.         delete itemizeStack.First();
  466.       }
  467.     }
  468.   }
  469.   else if (strcmp(name, "par") == 0)
  470.   {
  471.     if (start)
  472.       TexOutput("<P>\n");
  473.   }
  474.   else if (strcmp(name, "verbatim") == 0)
  475.   {
  476.     if (start)
  477.     {
  478.       char buf[100];
  479.       sprintf(buf, "<PRE>\n");
  480.       TexOutput(buf);
  481.     }
  482.     else TexOutput("</PRE>\n");
  483.   }
  484.   else if (strcmp(name, "centerline") == 0 || strcmp(name, "center") == 0)
  485.   {
  486. /*
  487.     if (start)
  488.     {
  489.       TexOutput("{\\qc ");
  490.     }
  491.     else TexOutput("}\\par\\pard\n");
  492. */
  493.   }
  494.   else if (strcmp(name, "flushleft") == 0)
  495.   {
  496. /*
  497.     if (start)
  498.     {
  499.       TexOutput("{\\ql ");
  500.     }
  501.     else TexOutput("}\\par\\pard\n");
  502. */
  503.   }
  504.   else if (strcmp(name, "flushright") == 0)
  505.   {
  506. /*
  507.     if (start)
  508.     {
  509.       TexOutput("{\\qr ");
  510.     }
  511.     else TexOutput("}\\par\\pard\n");
  512. */
  513.   }
  514.   else if (strcmp(name, "small") == 0)
  515.   {
  516. /*
  517.     if (start)
  518.     {
  519.       TexOutput("{\\fs16\n");
  520.     }
  521.     else TexOutput("}\n");
  522. */
  523.   }
  524.   else if (strcmp(name, "tiny") == 0)
  525.   {
  526. /*
  527.     if (start)
  528.     {
  529.       TexOutput("{\\fs12\n");
  530.     }
  531.     else TexOutput("}\n");
  532. */
  533.   }
  534.   else if (strcmp(name, "normalsize") == 0)
  535.   {
  536. /*
  537.     if (start)
  538.     {
  539.       TexOutput("{\\fs20\n");
  540.     }
  541.     else TexOutput("}\n");
  542. */
  543.   }
  544.   else if (strcmp(name, "large") == 0)
  545.   {
  546. /*
  547.     if (start)
  548.     {
  549.       TexOutput("{\\fs24\n");
  550.     }
  551.     else TexOutput("}\n");
  552. */
  553.   }
  554.   else if (strcmp(name, "LARGE") == 0)
  555.   {
  556.     if (start)
  557.     {
  558.       TexOutput("<H1>");
  559.     }
  560.     else TexOutput("</H1>");
  561.   }
  562.   else if (strcmp(name, "Large") == 0)
  563.   {
  564.     if (start)
  565.     {
  566.       TexOutput("<H1>");
  567.     }
  568.     else TexOutput("</H1>");
  569.   }
  570.   else if (strcmp(name, "bf") == 0)
  571.   {
  572.     if (start)
  573.     {
  574.       TexOutput("<B>");
  575.     }
  576.     else TexOutput("</B>");
  577.   }
  578.   else if (strcmp(name, "it") == 0)
  579.   {
  580.     if (start)
  581.     {
  582.       TexOutput("<I>");
  583.     }
  584.     else TexOutput("</I>");
  585.   }
  586.   else if (strcmp(name, "tt") == 0)
  587.   {
  588.     if (start)
  589.     {
  590.       TexOutput("<TT>");
  591.     }
  592.     else TexOutput("</TT>");
  593.   }
  594.   else if (strcmp(name, "sc") == 0)
  595.   {
  596.   }
  597.   else if (strcmp(name, "item") == 0)
  598.   {
  599.     if (start)
  600.     {
  601.       wxNode *node = itemizeStack.First();
  602.       if (node)
  603.       {
  604.         ItemizeStruc *struc = (ItemizeStruc *)node->Data();
  605.         struc->currentItem += 1;
  606. //        if (struc->currentItem > 1)
  607. //          TexOutput("<P>\n");
  608.         if (struc->listType == LATEX_DESCRIPTION)
  609.         {
  610.           if (descriptionItemArg)
  611.           {
  612.             TexOutput("<DT>");
  613.             TraverseChildrenFromChunk(descriptionItemArg);
  614.             TexOutput("\n");
  615.             descriptionItemArg = NULL;
  616.           }
  617.           TexOutput("<DD>");
  618.         }
  619.         else
  620.           TexOutput("<LI>");
  621.       }
  622.     }
  623.   }
  624.   else if (strcmp(name, "maketitle") == 0)
  625.   {
  626.     if (start && DocumentTitle && DocumentAuthor)
  627.     {
  628.       TexOutput("<H1>");
  629.       TraverseChildrenFromChunk(DocumentTitle);
  630.       TexOutput("</H1><P>\n\n");
  631.       TexOutput("<H3>");
  632.       TraverseChildrenFromChunk(DocumentAuthor);
  633.       TexOutput("</H3><P>\n\n");
  634.       if (DocumentDate)
  635.       {
  636.         TexOutput("<H3>");
  637.         TraverseChildrenFromChunk(DocumentDate);
  638.         TexOutput("</H3><P>\n\n");
  639.       }
  640.     }
  641.   }
  642.   else if (strcmp(name, "helpref") == 0 || strcmp(name, "helprefn") == 0)
  643.   {
  644.     if (start)
  645.     {
  646.       helpRefFilename = NULL;
  647.       helpRefText = NULL;
  648.     }
  649.   }
  650.   else if (strcmp(name, "bibliography") == 0)
  651.   {
  652.     if (start)
  653.     {
  654.       DefaultOnMacro(name, no_args, start);
  655.     }
  656.     else
  657.     {
  658.       DefaultOnMacro(name, no_args, start);
  659.       TexOutput("</DL>\n");
  660.     }
  661.   }
  662.   else if (strcmp(name, "hrule") == 0)
  663.   {
  664.     if (start)
  665.     {
  666.       TexOutput("<P>------------------------------------------------------------------<P>\n");
  667.     }
  668.   }
  669.   else if (strcmp(name, "tableofcontents") == 0)
  670.   {
  671.     if (start)
  672.     {
  673.       FILE *fd = fopen(ContentsName, "r");
  674.       if (fd)
  675.       {
  676.         char ch = getc(fd);
  677.         while (ch != EOF)
  678.         {
  679.           putc(ch, Titlepage);
  680.           ch = getc(fd);
  681.         }
  682.         fclose(fd);
  683.       }
  684.       else
  685.       {
  686.         TexOutput("RUN TEX2RTF AGAIN FOR CONTENTS PAGE\n");
  687.         OnInform("Run Tex2RTF again to include contents page.");
  688.       }
  689.     }
  690.   }
  691.   else DefaultOnMacro(name, no_args, start);
  692. }
  693.  
  694. // Called on start/end of argument examination
  695. Bool HTMLOnArgument(char *macro_name, int arg_no, Bool start)
  696. {
  697.   if ((strcmp(macro_name, "chapter") == 0) ||
  698.       (strcmp(macro_name, "chapter*") == 0) ||
  699.       (strcmp(macro_name, "myheading") == 0) ||
  700.       (strcmp(macro_name, "section") == 0) ||
  701.       (strcmp(macro_name, "section*") == 0) ||
  702.       (strcmp(macro_name, "subsection") == 0) ||
  703.       (strcmp(macro_name, "subsection*") == 0) ||
  704.       (strcmp(macro_name, "subsubsection") == 0) ||
  705.       (strcmp(macro_name, "subsubsection*") == 0) ||
  706.       (strcmp(macro_name, "gloss") == 0) ||
  707.       (strcmp(macro_name, "membersection") == 0) ||
  708.       (strcmp(macro_name, "functionsection") == 0))
  709.   {
  710.     if (!start && (arg_no == 1))
  711.       currentSection = GetArgChunk();
  712.   }
  713.   else if (strcmp(macro_name, "func") == 0)
  714.   {
  715.     if (start && (arg_no == 1))
  716.       TexOutput("<B>");
  717.  
  718.     if (!start && (arg_no == 1))
  719.       TexOutput("</B> ");
  720.  
  721.     if (start && (arg_no == 2))
  722.     {
  723.       if (!suppressNameDecoration) TexOutput("<B>");
  724.       currentMember = GetArgChunk();
  725.     }
  726.     if (!start && (arg_no == 2))
  727.     {
  728.       if (!suppressNameDecoration) TexOutput("</B>");
  729.     }
  730.     
  731.     if (start && (arg_no == 3))
  732.       TexOutput("(");
  733.     if (!start && (arg_no == 3))
  734.      TexOutput(")");
  735.   }
  736.   else if (strcmp(macro_name, "clipsfunc") == 0)
  737.   {
  738.     if (start && (arg_no == 1))
  739.       TexOutput("<B>");
  740.     if (!start && (arg_no == 1))
  741.       TexOutput("</B> ");
  742.  
  743.     if (start && (arg_no == 2))
  744.     {
  745.       if (!suppressNameDecoration) TexOutput("( ");
  746.       currentMember = GetArgChunk();
  747.     }
  748.     if (!start && (arg_no == 2))
  749.     {
  750.     }
  751.  
  752.     if (!start && (arg_no == 3))
  753.      TexOutput(")");
  754.   }
  755.   else if (strcmp(macro_name, "pfunc") == 0)
  756.   {
  757.     if (!start && (arg_no == 1))
  758.       TexOutput(" ");
  759.  
  760.     if (start && (arg_no == 2))
  761.       TexOutput("(*");
  762.     if (!start && (arg_no == 2))
  763.       TexOutput(")");
  764.  
  765.     if (start && (arg_no == 2))
  766.       currentMember = GetArgChunk();
  767.  
  768.     if (start && (arg_no == 3))
  769.       TexOutput("(");
  770.     if (!start && (arg_no == 3))
  771.       TexOutput(")");
  772.   }
  773.   else if (strcmp(macro_name, "param") == 0)
  774.   {
  775.     if (start && (arg_no == 1))
  776.       TexOutput("<B>");
  777.     if (!start && (arg_no == 1))
  778.       TexOutput("</B>");
  779.     if (start && (arg_no == 2))
  780.     {
  781.       TexOutput("<I>");
  782.     }
  783.     if (!start && (arg_no == 2))
  784.     {
  785.       TexOutput("</I>");
  786.     }
  787.   }
  788.   else if (strcmp(macro_name, "cparam") == 0)
  789.   {
  790.     if (start && (arg_no == 1))
  791.       TexOutput("<B>");
  792.     if (!start && (arg_no == 1))
  793.       TexOutput("</B> ");  // This is the difference from param - one space!
  794.     if (start && (arg_no == 2))
  795.     {
  796.       TexOutput("<I>");
  797.     }
  798.     if (!start && (arg_no == 2))
  799.     {
  800.       TexOutput("</I>");
  801.     }
  802.   }
  803.   else if (strcmp(macro_name, "member") == 0)
  804.   {
  805.     if (!start && (arg_no == 1))
  806.       TexOutput(" ");
  807.  
  808.     if (start && (arg_no == 2))
  809.       currentMember = GetArgChunk();
  810.   }
  811.  
  812.   else if (strcmp(macro_name, "helpref") == 0 || strcmp(macro_name, "helprefn") == 0)
  813.   {
  814.     if (IsArgOptional())
  815.     {
  816.       if (start)
  817.         helpRefFilename = GetArgChunk();
  818.       return FALSE;
  819.     }
  820.     else if ((GetNoArgs() - arg_no) == 1)
  821.     {
  822.       if (start)
  823.         helpRefText = GetArgChunk();
  824.       return FALSE;
  825.     }
  826.     else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
  827.     {
  828.       if (start)
  829.       {
  830.         char *refName = GetArgData();
  831.         char *refFilename = NULL;
  832.  
  833.         if (refName)
  834.         {
  835.           wxNode *node = TexReferences.Find(refName);
  836.           if (node)
  837.           {
  838.             TexRef *texRef = (TexRef *)node->Data();
  839.             if (texRef->refFile && strcmp(texRef->refFile, "??") != 0)
  840.               refFilename = texRef->refFile;
  841.  
  842.             TexOutput("<A HREF=\"");
  843.             // If a filename is supplied, use it, otherwise try to
  844.             // use the filename associated with the reference (from this document).
  845.             if (helpRefFilename)
  846.         {
  847.               TraverseChildrenFromChunk(helpRefFilename);
  848.               TexOutput("#");
  849.         }
  850.             else if (refFilename)
  851.         {
  852.               TexOutput(refFilename);
  853.               TexOutput("#");
  854.         }
  855.             TexOutput(refName);
  856.             TexOutput("\">");
  857.             if (helpRefText)
  858.               TraverseChildrenFromChunk(helpRefText);
  859.             TexOutput("</A>");
  860.           }
  861.         }
  862.         else TexOutput("??");
  863.       }
  864.       return FALSE;
  865.     }
  866.   }
  867.   else if (strcmp(macro_name, "psboxto") == 0 || strcmp(macro_name, "image") == 0)
  868.   {
  869.     if (arg_no == 2)
  870.     {
  871.       if (start)
  872.         TexOutput("<A HREF=\"");
  873.       else
  874.         TexOutput("\">Picture<P>\n");
  875.     }
  876.     else return FALSE;
  877.   }
  878.   else if (strcmp(macro_name, "item") == 0)
  879.   {
  880.     if (start && IsArgOptional())
  881.     {
  882.       descriptionItemArg = GetArgChunk();
  883.       return FALSE;
  884.     }
  885.   }
  886.   else if (strcmp(macro_name, "bibitem") == 0)
  887.   {
  888.     if (arg_no == 1 && start)
  889.       TexOutput("\n<DT>");
  890.     if (arg_no == 2 && start)
  891.       TexOutput("\n<DD>");
  892.     if (arg_no == 2 && !start)
  893.       TexOutput("<P>\n");
  894.   }
  895.   else return DefaultOnArgument(macro_name, arg_no, start);
  896.   return TRUE;
  897. }
  898.  
  899.  
  900. Bool HTMLGo(void)
  901. {
  902.   fileId = 0;
  903.   inVerbatim = FALSE;
  904.   indentLevel = 0;
  905.  
  906.   if (InputFile && OutputFile)
  907.   {
  908.     // Do some HTML-specific transformations on all the strings,
  909.     // recursively
  910.     Text2HTML(GetTopLevelChunk());
  911.  
  912.     char buf[300];
  913.     sprintf(buf, "%s_contents.html", FileRoot);
  914.     Titlepage = fopen(buf, "w");
  915.  
  916.     Contents = fopen(TmpContentsName, "w");
  917.     if (!Titlepage || !Contents)
  918.     {
  919.       OnError("Cannot open output file!");
  920.       return FALSE;
  921.     }
  922.  
  923.     fprintf(Contents, "<P><P><H1>Contents</H1><P><P>\n");
  924.  
  925.     fprintf(Contents, "<UL>\n");
  926.  
  927.     SetCurrentOutput(Titlepage);
  928.     OnInform("Converting...");
  929.  
  930.     TraverseDocument();
  931.  
  932.     if (DocumentTitle)
  933.     {
  934.       SetCurrentOutput(Titlepage);
  935.       TexOutput("\n<TITLE>");
  936.       TraverseChildrenFromChunk(DocumentTitle);
  937.       TexOutput("</TITLE>\n");
  938.     }
  939.     else
  940.     {
  941.       if (contentsString)
  942.         fprintf(Titlepage, "<TITLE>%s</TITLE>\n\n", contentsString);
  943.       else
  944.         fprintf(Titlepage, "<TITLE>%s</TITLE>\n\n", FileNameFromPath(FileRoot));
  945.     }
  946.  
  947.     fprintf(Contents, "</UL>\n\n");
  948.     if (Titlepage)
  949.       fclose(Titlepage);
  950.     if (Contents)
  951.       fclose(Contents);
  952.     if (Chapters)
  953.       fclose(Chapters);
  954.     if (Sections)
  955.       fclose(Sections);
  956.     if (Subsections)
  957.       fclose(Subsections);
  958.     if (Subsubsections)
  959.       fclose(Subsubsections);
  960.  
  961.     if (FileExists(ContentsName)) wxRemoveFile(ContentsName);
  962.     wxRenameFile(TmpContentsName, ContentsName);
  963.  
  964.     return TRUE;
  965.   }
  966.   return FALSE;
  967. }
  968.  
  969.